package com.gilight.base.controller.uiapp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gilight.base.admin.brand.AdminBrandService;
import com.gilight.base.aspect.annotation.Auth;
import com.gilight.base.base.ResultEntity;
import com.gilight.base.base.exception.AppServiceException;
import com.gilight.base.base.exception.ServiceException;
import com.gilight.base.common.Const;
import com.gilight.base.component.CacheComponent;
import com.gilight.base.component.CacheConst;
import com.gilight.base.dao.SysZzjgMapper;
import com.gilight.base.dto.freight.ShipTraceDTO;
import com.gilight.base.dto.order.OrderDTO;
import com.gilight.base.dto.order.OrderRequestDTO;
import com.gilight.base.dto.uni.UserDTO;
import com.gilight.base.mapper.OrderMapper;
import com.gilight.base.model.BrandDo;
import com.gilight.base.model.Page;
import com.gilight.base.model.SysZzjg;
import com.gilight.base.model.order.OrderSkuDO;
import com.gilight.base.service.SysZzjgService;
import com.gilight.base.service.impl.UserBizService;
import com.gilight.base.uiapp.category.CategoryService;
import com.gilight.base.uiapp.order.OrderService;
import com.gilight.base.util.SessionUtil;
import com.gilight.base.wx.WeChatCommonTemplateMessageModel;
import com.gilight.base.wx.WeChatTemplateValueModel;
import io.swagger.annotations.ApiOperation;
import org.omg.CORBA.portable.ApplicationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * @author liken
 * 商品管理控制类
 */
@RestController
@RequestMapping("/web/app-order")
public class AppOrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private CacheComponent cacheComponent;

    @Autowired
    private SysZzjgService sysZzjgService;

    @Autowired
    private UserBizService userBizService;

    @Autowired
    private AdminBrandService adminBrandService;
    /**
     *
     * @param orderRequest  订单请求实例
     * @param channel       订单提交渠道
     * @param userId
     * @param isBaiHuo 0代表是冷饮单 1 代表百货单
     * @return
     * @throws ServiceException
     */
    @ApiOperation(value = "下单")
    @RequestMapping(value = "/take-order")
    @Auth
    public ResultEntity takeOrder(
            String orderRequest,
            String channel,
            Long userId,
            Long zzjgId,
            Integer isBaiHuo,
            HttpServletRequest request) throws ServiceException{
        String ip = (String) request.getAttribute("currentGeo");
        ResultEntity resultEntity = ResultEntity.success();
        String accessToken = request.getHeader(Const.USER_ACCESS_TOKEN);
        UserDTO userDTO = null;
        if (!StringUtils.isEmpty(accessToken)) {
            String userJson = userRedisTemplate.opsForValue().get(Const.USER_REDIS_PREFIX + accessToken);
            if (!StringUtils.isEmpty(userJson)) {
                userDTO = JSONObject.parseObject(userJson, UserDTO.class);
            }
        }

        OrderRequestDTO orderRequestDTO = JSON.parseObject(orderRequest,OrderRequestDTO.class);
        resultEntity.setData(orderService.takeOrder(orderRequestDTO,channel,userId,zzjgId,isBaiHuo,userDTO,ip));



        return resultEntity;

    }
    @Autowired
    private StringRedisTemplate userRedisTemplate;
    /**
     * 获取订单分页
     * @param pageNo
     * @param pageSize
     * @param status 订单状态
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "获取订单分页")
    @RequestMapping(value = "/get-order-page")
    public ResultEntity getOrderPage(
            Integer pageNo,
            Integer pageSize,
            Integer status,
            Long userId,
            Long zzjgId) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        List<Long> zzjgIds = new ArrayList<>();
        zzjgIds.add(zzjgId);
        resultEntity.setData(orderService.getOrderPage(pageNo,pageSize,status,userId,zzjgIds));
        return resultEntity;
    }
    /**
     * 获取订单分页
     * @param pageNo
     * @param pageSize
     * @param status 订单状态
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "根据状态列表获取订单分页")
    @RequestMapping(value = "/get-order-page-status")
    public ResultEntity getOrderPageStatus(
            Integer pageNo,
            Integer pageSize,
            String status,
            Long userId,
            Long zzjgId) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        if(StringUtils.isEmpty(status)){
            throw new RuntimeException();
        }
        String [] statusSplit = status.split(",");
        List<Integer> statusArray = new ArrayList<>();
        Arrays.stream(statusSplit).forEach(item->{
            statusArray.add(Integer.valueOf(item));
        });

        List<Long> zzjgIds = new ArrayList<>();
        if(zzjgId != null){
            zzjgIds = sysZzjgService.findIdsByParentId(zzjgId);
        }
        //TODO 当用户查询订单时是否只查到当前选择店铺的订单，还是要查询所有的
        resultEntity.setData(orderService.getOrderPageStatus(pageNo,pageSize,statusArray,SessionUtil.getUser().getId(),zzjgIds));
        return resultEntity;
    }
    /**
     * 获取订单分页
     * @return
     * @throws ServiceException
     */
    @ApiOperation(value = "获取正在制作的单数")
    @RequestMapping(value = "/get-order-in-cook-count")
    public ResultEntity getInCook(
            Long zzjgId,Long userId) {
        ResultEntity resultEntity = ResultEntity.success();
        resultEntity.setData(orderService.getInCook(zzjgId));
        return resultEntity;
    }
    /**
     * 获取订单详情
     * @param orderId
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "获取订单详情")
    @RequestMapping(value = "/get-order-detail")
    public ResultEntity getOrderDetail(
            Long orderId,
            Long userId,String orderNo)throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        resultEntity.setData(orderService.getOrderDetail(orderId,userId,orderNo));
        return resultEntity;
    }

    /**微信小程序预先支付
     *
     * @param parentOrderNo 父单串号
     * @param orderNo       订单串号
     * @param ip            ip地址
     * @param userId        用户Id
     * @param zzjgId        当前下单的店面
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "微信小程序预先支付")
    @RequestMapping(value = "/wx-prepay")
    public ResultEntity wxPrepay(
            String parentOrderNo,
            String orderNo,
            String ip,
            Long userId,
            Long zzjgId,
            HttpServletRequest request) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        String accessToken = request.getHeader(Const.USER_ACCESS_TOKEN);
        UserDTO userDTO = null;
        if (!StringUtils.isEmpty(accessToken)) {
            String userJson = userRedisTemplate.opsForValue().get(Const.USER_REDIS_PREFIX + accessToken);
            if (!StringUtils.isEmpty(userJson)) {
                userDTO = JSONObject.parseObject(userJson, UserDTO.class);
            }
        }
        Object object = orderService.wxPrepay(parentOrderNo,orderNo,ip,userId,zzjgId,userDTO);
        cacheComponent.putObj(CacheConst.WX_PREPAY_ORDER+parentOrderNo,object,60*20);
        resultEntity.setData(object);
        return resultEntity;
    }
    @Auth
    @ApiOperation(value = "微信小程序预先支付失败时获取已经预计下单信息不进行重复下单")
    @RequestMapping(value = "/wx-prepay-get-pre")
    public ResultEntity wxGetPrepay(
            String parentOrderNo
               ) throws ServiceException{
        Object object = null;
        ResultEntity resultEntity = new ResultEntity();
        if(cacheComponent.hasKey(CacheConst.WX_PREPAY_ORDER+parentOrderNo)){//说明还在支付时效内事实上订单的超时是10分钟，而前端只会有5分钟的超时操作机会
            object = cacheComponent.getObj(CacheConst.WX_PREPAY_ORDER+parentOrderNo,Object.class);
        }
        resultEntity.setData(object);
        return resultEntity;
    }
    /**线下支付
     *
     * @param parentOrderNo
     * @param orderNo
     * @param userId
     * @return
     * @throws ServiceException
     */
    @ApiOperation(value = "线下支付")
    @RequestMapping(value = "/offline-prepay")
    public Object offlinePrepay(
            String parentOrderNo,
            String orderNo,
            Long userId) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        resultEntity.setData(orderService.offlinePrepay(parentOrderNo,orderNo,userId));
        return resultEntity;
    }

    /**用户申请退款
     *
     * @param orderNo 订单串号
     * @param reason  退款理由
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "用户申请退款")
    @RequestMapping(value = "/refund")
    public ResultEntity refund(
            String orderNo,
            String reason,
            Long userId) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        resultEntity.setData(orderService.refund(orderNo,reason,userId));
        return resultEntity;
    }

    /**
     *
     * @param orderNo   取消订单
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "取消订单")
    @RequestMapping(value = "/cancel")
    public ResultEntity cancel(
            String orderNo,
            Long userId) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        resultEntity.setData(orderService.cancel(orderNo,userId));
        return resultEntity;
    }

    /**
     * 确认订单
     * @param orderNo
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "确认订单")
    @RequestMapping(value = "/confirm")
    public ResultEntity confirm(
            String orderNo,
            Long userId) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        resultEntity.setData(orderService.confirm(orderNo,userId));
        return resultEntity;
    }

    /**
     * 查询物流
     * @param orderNo
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "查询物流")
    @RequestMapping(value = "/query-ship")
    public ResultEntity queryShip(
            String orderNo,
            Long userId) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        resultEntity.setData(orderService.queryShip(orderNo,userId));
        return resultEntity;
    }

    /**
     * 预览邮费
     * @param orderRequest  用户欲下单
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Auth
    @ApiOperation(value = "预览邮费")
    @RequestMapping(value = "/preview-freight")
    public ResultEntity previewFreight(
            OrderRequestDTO orderRequest,
            Long userId) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        resultEntity.setData(orderService.previewFreight(orderRequest,userId));
        return resultEntity;
    }

    @ApiOperation(value = "预览邮费")
    @RequestMapping(value = "/test")
    public ResultEntity test(
          ) throws ServiceException{
        ResultEntity resultEntity = ResultEntity.success();
        List<Long> ids = sysZzjgService.findIdsByParentId(1L);
        resultEntity.setData(ids);
        return resultEntity;
    }

    @Auth
    @RequestMapping(value = "/check-auth")
    public void checkHasAuth(){

    }
    private OrderMapper orderMapper;
    @Auth
    @RequestMapping(value = "/send-noty")
    public void sendNotifyTakeNotyfile(
             Long brandId
            ,String openId
            ,Long zzjgId
            ,String templateId
            ,String page
            ,String orderNo){
        BrandDo brand = adminBrandService.getById(brandId);
        String appId = brand.getMiniAppId();
        String appSec = brand.getMiniAppSec();

        try {
            SysZzjg zzjg = sysZzjgService.getSysZzjgById(zzjgId);
            OrderDTO orderDTO = orderService.getOrderDetail(null,null,orderNo);
            String quCanMa = orderDTO.getSpecOrder();
            if(org.apache.commons.lang3.StringUtils.isEmpty(quCanMa)){
                quCanMa = "1";
            }
            quCanMa = quCanMa.replace("M","");
            Date date = orderDTO.getGmtCreate(); //聚餐时间
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String stringDate = simpleDateFormat.format(date); //下单时间
            String skuTiles ="饮品";

            List<Map<String, Object>> orderSkuDOMaps = orderService.getOrderSku(orderDTO.getOrderNo());
            for(Map<String,Object> item : orderSkuDOMaps){
                skuTiles+=item.get("title")+"等"+orderSkuDOMaps.size()+"个饮品";
                break;
            }
            String accessToken = userBizService.getWxMiniAccessToken(appId,appSec);
            String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="+accessToken;
            WeChatCommonTemplateMessageModel model = new WeChatCommonTemplateMessageModel();
            model.setTouser(openId);
            model.setTemplate_id(templateId);
            model.setPage("pages/order/detail?id=" + orderDTO.getId());
            Map<String, WeChatTemplateValueModel> datas = new HashMap<>();
            WeChatTemplateValueModel vModel = new WeChatTemplateValueModel();
            vModel.setValue(quCanMa);
            datas.put("number1",vModel);
            WeChatTemplateValueModel vModelDate = new WeChatTemplateValueModel();
            vModelDate.setValue(stringDate);
            datas.put("date4",vModelDate);
            WeChatTemplateValueModel vModelSkuTitle= new WeChatTemplateValueModel();
            vModelSkuTitle.setValue(skuTiles);
            datas.put("thing5",vModelSkuTitle);
            WeChatTemplateValueModel vModelZzjgName= new WeChatTemplateValueModel();
            vModelZzjgName.setValue(zzjg.getZzjgName());
            datas.put("name8",vModelZzjgName);

            WeChatTemplateValueModel vModelToUser= new WeChatTemplateValueModel();
            vModelToUser.setValue(zzjg.getZzjgName());
            datas.put("name15",vModelToUser);
            model.setData(datas);
            userBizService.wechatCommonTemplateMessage(model,url);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
